#include "./BSP/ADS1115/Drv_ADS1115.h"
#include "./SYSTEM/usart/usart.h"
//#include "cmd_process.h" //提供结构体定义支持
#include "./SYSTEM/delay/delay.h" //提供延时函数支持

extern char g_CarryGas_Type;  //气体种类，换算公式用
extern float gTestFlowRaw;//测试打印用
extern uint16_t gTestFlowRawHex;//测试打印用


static ADS1115_InitTypeDefine ADS1115_InitType_Chip1;
//static ADS1115_InitTypeDefine ADS1115_InitType_Chip2;

/**
 * 可供外部调用的全局变量，记录了ADS1115采样的原始16位数据。调用void ADS1115_RefreshAllChannel( )函数可以刷新这个变量。
 * 通过定义宏ADS1115_USE_FILTER，可以将ADS1115的轮询采样数据经过滑动滤波后，保存到ADS1115_RawData[]中。
 * 通过float ADS1115_RawDataToVoltage(int16_t rawData)函数可以将ADS1115_RawData[]换算成对应的电压值。
 */
int16_t ADS1115_RawData[ADS1115_CHIP1_MAX_CHANNEL+ADS1115_CHIP2_MAX_CHANNEL] = {0};

/**
 * @brief 完成芯片控制端口初始化，并设置初始状态
 */
void ADS1115_Init(void)
{
	//I2C_Virtual_ConfigPort(ADS1115_SDA_PORT, ADS1115_SDA_PIN, ADS1115_SCL_PORT, ADS1115_SCL_PIN);
}


/**
 * @brief Configuration of ADS1115, single-shot
 *        default ADS1115_MUX_Channel_0 : AINp=AIN0, AINn=GND
 */
uint8_t ADS1115_UserConfig1(void)
{
	ADS1115_InitType_Chip1.COMP_LAT = ADS1115_COMP_LAT_0;
	ADS1115_InitType_Chip1.COMP_MODE = ADS1115_COMP_MODE_0;
	ADS1115_InitType_Chip1.COMP_POL = ADS1115_COMP_POL_0;
	ADS1115_InitType_Chip1.DataRate = ADS1115_DataRate_128;
	ADS1115_InitType_Chip1.MODE = ADS1115_MODE_SingleConver;
	ADS1115_InitType_Chip1.MUX = ADS1115_MUX_Channel_0;
	ADS1115_InitType_Chip1.OS = ADS1115_OS_SingleConverStart;
	ADS1115_InitType_Chip1.PGA = ADS1115_PGA_4096;
	if( !ADS1115_Config(ADS1115_ADDRESS_CHIP1,&ADS1115_InitType_Chip1))
		return 0;
	
//	ADS1115_InitType_Chip2.COMP_LAT = ADS1115_COMP_LAT_0;
//	ADS1115_InitType_Chip2.COMP_MODE = ADS1115_COMP_MODE_0;
//	ADS1115_InitType_Chip2.COMP_POL = ADS1115_COMP_POL_0;
//	ADS1115_InitType_Chip2.DataRate = ADS1115_DataRate_128;
//	ADS1115_InitType_Chip2.MODE = ADS1115_MODE_SingleConver;
//	ADS1115_InitType_Chip2.MUX = ADS1115_MUX_Channel_0;
//	ADS1115_InitType_Chip2.OS = ADS1115_OS_SingleConverStart;
//	ADS1115_InitType_Chip2.PGA = ADS1115_PGA_4096;
//	if( !ADS1115_Config(ADS1115_ADDRESS_CHIP2,&ADS1115_InitType_Chip2))
//		return 0;
	
	return 1;
}


/**
 * @brief Configuration of ADS1115, continuous conversion,
 *        default ADS1115_MUX_Channel_0 : AINp=AIN0, AINn=GND
 */
uint8_t ADS1115_UserConfig2(void)
{
	ADS1115_InitType_Chip1.COMP_LAT = ADS1115_COMP_LAT_0;
	ADS1115_InitType_Chip1.COMP_MODE = ADS1115_COMP_MODE_0;
	ADS1115_InitType_Chip1.COMP_POL = ADS1115_COMP_POL_0;
	ADS1115_InitType_Chip1.DataRate = ADS1115_DataRate_128;
	ADS1115_InitType_Chip1.MODE = ADS1115_MODE_ContinuConver;
	ADS1115_InitType_Chip1.MUX = ADS1115_MUX_Channel_0;
	ADS1115_InitType_Chip1.OS = ADS1115_OS_OperationalStatus;
	ADS1115_InitType_Chip1.PGA = ADS1115_PGA_4096;

	return ADS1115_Config(ADS1115_ADDRESS_CHIP1,&ADS1115_InitType_Chip1);
}


/**
 * @brief 配置ADS1115
 * @param ADS1115_InitStruct: 用来配置ADS1115的结构体变量指针
 * @return 配置结果
 * 		@arg: fail
 * 		@arg: success
 */
uint8_t ADS1115_Config(uint8_t addr,ADS1115_InitTypeDefine *ADS1115_InitStruct)
{

	uint16_t Config;
	uint8_t Writebuff[2];

	Config = ADS1115_InitStruct->OS + ADS1115_InitStruct->MUX + ADS1115_InitStruct->PGA + ADS1115_InitStruct->MODE
			+ ADS1115_InitStruct->DataRate + ADS1115_InitStruct->COMP_MODE + ADS1115_InitStruct->COMP_POL
			+ ADS1115_InitStruct->COMP_LAT + ADS1115_InitStruct->COMP_QUE;

	Writebuff[0] = (unsigned char) ((Config >> 8) & 0xFF);
	Writebuff[1] = (unsigned char) (Config & 0xFF);


	I2C_Virtual_Start();					//启动总线

	I2C_Virtual_SendByte(ADS1115_IIC_W(addr));		//发送器件地址（写）

	if (I2C_Virtual_ack == 0)
		return (0);

	I2C_Virtual_SendByte(ADS1115_Pointer_ConfigReg);		//发送寄存器地址

	if (I2C_Virtual_ack == 0)
		return (0);

	I2C_Virtual_SendByte(Writebuff[0]);		//发送数据

	if (I2C_Virtual_ack == 0)
		return (0);

	I2C_Virtual_SendByte(Writebuff[1]);		//发送数据

	if (I2C_Virtual_ack == 0)
		return (0);

	I2C_Virtual_Stop();
	return (1);
}



/**
 * @brief 读取ADS1115当前通道下的原始数据
 * @param rawData: 传入一个int16_t整型变量的指针，ADS1115的原始数据将保存在这个变量中
 * @return 读取结果
 * 		@arg 0: fail
 * 		@arg 1: success
 */
uint8_t ADS1115_ReadRawData(uint8_t addr,int16_t *rawData)
{
	unsigned char Result[2];

	I2C_Virtual_Start();															//启动总线
	I2C_Virtual_SendByte(ADS1115_IIC_W(addr));					//发送器件地址（写）

	if (I2C_Virtual_ack == 0)
		return (0);

	I2C_Virtual_SendByte(ADS1115_Pointer_ConverReg); 	//发送寄存器地址

	if (I2C_Virtual_ack == 0)
		return (0);

	I2C_Virtual_Stop();
	delay_us(10);
	I2C_Virtual_Start();											//写寄存器之后需要重新启动总线

	I2C_Virtual_SendByte(ADS1115_IIC_R(addr));						//发送器件地址（读）

	if (I2C_Virtual_ack == 0)
		return (0);

	Result[0] = I2C_Virtual_RcvByte();		//接收数据
	I2C_Virtual_Ack();			//发送就答位
	Result[1] = I2C_Virtual_RcvByte();
	I2C_Virtual_NoAck();			//发送非应位
	I2C_Virtual_Stop(); 			//结束总线

	*rawData = (int16_t) (((Result[0] << 8) & 0xFF00) | (Result[1] & 0xFF));

	return 1;
}


/**
 * @brief Switch the channel of ADS1115
 * @param channel
 */
void ADS1115_ScanChannel(uint8_t addr,uint8_t channel)
{
	if(addr == ADS1115_ADDRESS_CHIP1)
	{
		switch (channel)
		{
		case 0x00:
			//ADS1115_InitType_Chip1.PGA = ADS1115_PGA_6144;
			ADS1115_InitType_Chip1.MUX = ADS1115_MUX_Channel_0;
			break;
		case 0x01:
			//ADS1115_InitType_Chip1.PGA = ADS1115_PGA_6144;
			ADS1115_InitType_Chip1.MUX = ADS1115_MUX_Channel_1;
			break;
		case 0x02:
			//ADS1115_InitType_Chip1.PGA = ADS1115_PGA_2048;
			ADS1115_InitType_Chip1.MUX = ADS1115_MUX_Differ_23;
			break;
		default:
			break;
		}
		ADS1115_Config(addr,&ADS1115_InitType_Chip1);
	}
//	else if(addr == ADS1115_ADDRESS_CHIP2)
//	{
//		switch (channel)
//		{
//		case 0x03:
//			ADS1115_InitType_Chip2.MUX = ADS1115_MUX_Channel_0;
//			break;
//		case 0x04:
//			ADS1115_InitType_Chip2.MUX = ADS1115_MUX_Channel_1;
//			break;
//		case 0x05:
//			ADS1115_InitType_Chip2.MUX = ADS1115_MUX_Channel_2;
//			break;
//		case 0x06:
//			ADS1115_InitType_Chip2.MUX = ADS1115_MUX_Channel_3;
//			break;
//		default:
//			break;
//		}
//		ADS1115_Config(addr,&ADS1115_InitType_Chip2);

//	}
//	else
//	{
//		//芯片地址非法
//	}

}


/**
 * @brief 将传感器的原始采样数据转化为电压数据，
 * 			根据ADS1115_InitType结构体中包含的增益信息计算
 * @param rawData: 待转换的原始数据
 * @retval 返回经过计算的电压值
 */
float ADS1115_RawDataToVoltage(uint8_t addr,int16_t rawData)
{
	float voltage;
	float rawVoltage = (float)rawData/32767.0f;
	uint16_t tempPGC = 0;
	if(addr == ADS1115_ADDRESS_CHIP1)
	{
		tempPGC = ADS1115_InitType_Chip1.PGA;
	}
//	else if(addr == ADS1115_ADDRESS_CHIP2)
//	{
//		tempPGC = ADS1115_InitType_Chip2.PGA;
//	}
//	else
//	{
//		//芯片地址非法
//	}
	
	switch (tempPGC)
	{
		case ADS1115_PGA_0256:
			voltage = rawVoltage * 0.256;
			break;

		case ADS1115_PGA_0512:
			voltage = rawVoltage * 0.512;
			break;

		case ADS1115_PGA_1024:
			voltage = rawVoltage * 1.024;
			break;

		case ADS1115_PGA_2048:
			voltage = rawVoltage * 2.048;
			break;

		case ADS1115_PGA_4096:
			voltage = rawVoltage * 4.096;
			break;

		case ADS1115_PGA_6144:
			voltage = rawVoltage * 6.144;
			break;

		default:
			voltage = 0;
			break;
	}

	return voltage;
}


/**
 * @brief 直接获取ADS1115当前通道的电压采样值
 * @return 电压采样值
 */
float ADS1115_GetVoltage(uint8_t addr)
{
	int16_t rawData;

	ADS1115_ReadRawData(addr,&rawData);

	return ADS1115_RawDataToVoltage(addr,rawData);
}

/**
 * @brief 刷新ADS1115全部通道的采样数据
 * 		由于ADS1115通道切换后需要等待较长时间数据才能够稳定，
 * 		在进行多路数据采集的时候，切换通道后延时阻塞等待切换完成会占用过多的系统时间，
 * 		因此需要在一个定时器中轮询采集ADS1115数据，每次采集完成后，切换到下一个通道
 * 		大幅度提高了系统工作的效率。
 *
 * 		调用此函数可以刷新全局变量ADS1115_RawData[4]的值。
 *
 * 		应当在一个定时器更新中断服务函数中周期性的调用此函数，更新周期最好小于200Hz
 */
void ADS1115_RefreshSingleChipChannel(uint8_t addr,int16_t* data)
{
	static uint8_t channel = 0;
	int16_t adcDataTemp = 0;
	uint8_t allChannel = 0;
	if(addr == ADS1115_ADDRESS_CHIP1)
		allChannel = ADS1115_ADDRESS_CHIP1;
//	if(addr == ADS1115_ADDRESS_CHIP2)
//		allChannel = ADS1115_ADDRESS_CHIP2;
	else
		return;

	//通道切换时可能有不确定的数据读出，因此需要将前1~2次读出的数据舍弃
	ADS1115_ReadRawData(addr,&adcDataTemp);

	//读取数据返回正确，则将读到的数据写入ADS1115_RawData数组中
	if( ADS1115_ReadRawData(addr,&adcDataTemp) !=0 )
	{
		data[channel] = adcDataTemp;
	}
	
	//ADS1115总共4个通道
	channel++;

	if(channel>allChannel-1)
		channel = 0;

	//结束采样后切换至下一通道
	ADS1115_ScanChannel(addr,channel);
}

void ADS1115_RefreshAllChannel()
{
	static uint8_t channel = 0,addr=ADS1115_ADDRESS_CHIP1;
	int16_t adcDataTemp = 0;	

	//通道切换时可能有不确定的数据读出，因此需要将前1~2次读出的数据舍弃
	ADS1115_ReadRawData(addr,&adcDataTemp);

	//读取数据返回正确，则将读到的数据写入ADS1115_RawData数组中
	if( ADS1115_ReadRawData(addr,&adcDataTemp) !=0 )
	{
		ADS1115_RawData[channel] = adcDataTemp;
	}
	
	channel++;
	if(channel>ADS1115_CHIP1_MAX_CHANNEL+ADS1115_CHIP2_MAX_CHANNEL-1)
		channel = 0;
	
	if(channel<ADS1115_CHIP1_MAX_CHANNEL)
		addr = ADS1115_ADDRESS_CHIP1;
	else if(channel>=ADS1115_CHIP1_MAX_CHANNEL
		&&channel<ADS1115_CHIP1_MAX_CHANNEL+ADS1115_CHIP2_MAX_CHANNEL)
//		addr = ADS1115_ADDRESS_CHIP2;
	
	//结束采样后切换至下一通道
	ADS1115_ScanChannel(addr,channel);
}



